home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / lantimes / 90_03 / nb.c next >
Text File  |  1989-12-11  |  7KB  |  249 lines

  1. /*--------------------------------------------------------------------------*
  2.  * nb.c -- C interface to the netbios
  3.  *
  4.  * The routines in this package provide a simplified C method of access
  5.  * to the NetBios. The simplifications are achieved by assuming that
  6.  * each network interface card (NIC) has only one assigned name (in addition
  7.  * to its permanent name), and hence that only one name number is required.
  8.  *
  9.  * The global conventions are as follows:
  10.  *
  11.  *      Routines return 0 for failure, non-0 for success. In case of
  12.  *      failure, the variable nb_errno contains the NetBios error
  13.  *      number from the last request. In case of success, the return
  14.  *      code may be a name number or a session number or neither,
  15.  *      depending on context.
  16.  *
  17.  *      Routines that wait for completion before returning use
  18.  *      a static NCB and maintain all of its fields. Routines
  19.  *      that return immediately ("no wait" forms) use an NCB initialized
  20.  *      and supplied by the caller.
  21.  *
  22.  *      NetBios routines may be called from within POST routines,
  23.  *      bearing in mind that the just-completed NCB may not be
  24.  *      reused, and DOS functions may only be called if the reentrancy
  25.  *      check permits them.
  26.  *
  27.  * Compiler: Microsoft C V5.0. Stack probes removed by #pragma.
  28.  *
  29.  * Tom Nolan - 9/20/89
  30.  *
  31.  *-------------------------------------------------------------------------*/
  32.  
  33. #include <dos.h>
  34. #include "netbios.h"
  35.  
  36. static union REGS regs;
  37. static struct SREGS sregs;
  38. static NCB ncb;
  39.  
  40. int nb_errno;
  41.  
  42. #pragma check_stack(off)
  43.  
  44. /*-------------------------------------------------------------------------*/
  45. int isnodename(char *str)                    /* check if a string is a node name    */
  46. {
  47.     int len = strlen(str);
  48.  
  49.     return(len > 1 && len <= NODE_NAME_LEN && str[0] == '\\' && \
  50.         str[1] == '\\');
  51. }
  52.  
  53. /*-------------------------------------------------------------------------*/
  54. void namecpy(char *dst, char *src)        /* copy name, padding with nulls        */
  55. {
  56.     int i;
  57.  
  58.     for(i = 0; (i < NODE_NAME_LEN) && *src; i++)
  59.         *dst++ = *src++;
  60.     for( ; i < NODE_NAME_LEN; i++)
  61.         *dst++ = '\0';
  62. }
  63.  
  64. /*-------------------------------------------------------------------------*/
  65. void clear_ncb(NCB *ncb_ptr)                                    /* zero out an NCB    */
  66. {
  67.     int i;
  68.     char *char_ptr = (char *) ncb_ptr;
  69.  
  70.     for(i = 0; i < sizeof(NCB); i++)
  71.         *char_ptr++ = 0;
  72. }
  73.  
  74. /*-------------------------------------------------------------------------*/
  75. int nb_request(int cmd, NCB *ncb_ptr)         /* issue NetBIOS request        */
  76. {
  77.     segread(&sregs);
  78.  
  79.     ncb_ptr->command = cmd;
  80.     sregs.es = sregs.ds;
  81.     regs.x.bx = (int) ncb_ptr;
  82.     int86x(NB_INT, ®s, ®s, &sregs);
  83.     return(nb_errno = regs.h.al);
  84. }
  85.  
  86. /*-------------------------------------------------------------------------*/
  87. int nb_cancel(NCB *ncb_ptr)                        /* cancel a NetBIOS request    */
  88. {
  89.     clear_ncb(&ncb);
  90.     ncb.buffer = (char *) ncb_ptr;
  91.     return(!nb_request(NB_CANCEL, &ncb));
  92. }
  93.  
  94. /*-------------------------------------------------------------------------*/
  95. int get_name(char *str)                    /* get my own node name                        */
  96. {
  97.     char status[78];                        /* status buffer (60 bytes + 18 bytes) */
  98.  
  99.     *(int *)(status+58) = 0;            /* in case NetBIOS isn't there...        */
  100.     clear_ncb(&ncb);
  101.     ncb.buffer = (char far *) status;
  102.     ncb.length = sizeof(status);
  103.     strcpy(ncb.callname, "*");
  104.     nb_request(NB_ADAPTER_STATUS, &ncb);    /* issue status request                */
  105.     if(*(int *)(status+58) == 0)                /* if no name table entries        */
  106.         return(0);                                    /* ...failure                            */
  107.     namecpy(str, status+60);                    /* copy out 1st name table entry    */
  108.     return(2);                                        /* which is name for name num 2    */
  109. }
  110.  
  111. /*-------------------------------------------------------------------------*/
  112. int reset(void)                                    /* reset the NIC                        */
  113. {
  114.     clear_ncb(&ncb);
  115.     return(!nb_request(NB_RESET, &ncb));
  116. }
  117.  
  118. /*-------------------------------------------------------------------------*/
  119. int add_name(char *str)                    /* add a node name to the name table    */
  120. {
  121.     int err;
  122.  
  123.     clear_ncb(&ncb);
  124.     namecpy(ncb.name, str);
  125.     err = nb_request(NB_ADD_NAME, &ncb);
  126.     if(!err || (err == 0x0d))
  127.         return(ncb.num);
  128.     else
  129.         return(0);
  130. }
  131.  
  132. /*-------------------------------------------------------------------------*/
  133. int call(char *remote, char *local)            /* call remote NIC by node name    */
  134. {
  135.     int err;
  136.  
  137.     clear_ncb(&ncb);
  138.     namecpy(ncb.callname, remote);
  139.     namecpy(ncb.name, local);
  140.     ncb.sto = ncb.rto = 60;
  141.     err = nb_request(NB_CALL, &ncb);
  142.     if(err)
  143.         return(0);
  144.     else
  145.         return(ncb.lsn);
  146. }
  147.  
  148. /*-------------------------------------------------------------------------*/
  149. int listen(char *remote, char *local)        /* listen for a call from a        */
  150. {                                                        /* remote NIC                            */
  151.     clear_ncb(&ncb);
  152.     namecpy(ncb.callname, remote);
  153.     namecpy(ncb.name, local);
  154.     ncb.sto = ncb.rto = 60;
  155.     if(nb_request(NB_LISTEN, &ncb))
  156.         return(0);
  157.     else
  158.         return(ncb.lsn);
  159. }
  160.  
  161. /*-------------------------------------------------------------------------*/
  162. int send_datagram(char *node, void *buf, int len)    /* send datagram to a    */
  163. {                                                                    /* named node                */
  164.     clear_ncb(&ncb);
  165.     ncb.num = 2;
  166.     ncb.buffer = (char far *) buf;
  167.     ncb.length = len;
  168.     namecpy(ncb.callname, node);
  169.     return(!nb_request(NB_SEND_DATAGRAM, &ncb));
  170. }
  171.  
  172. /*-------------------------------------------------------------------------*/
  173. int send_brdcst_datagram(void *buf, int len)    /* send a broadcast datagram    */
  174. {
  175.     clear_ncb(&ncb);
  176.     ncb.num = 2;
  177.     ncb.buffer = (char far *) buf;
  178.     ncb.length = len;
  179.     return(!nb_request(NB_SEND_BDATAGRAM, &ncb));
  180. }
  181.  
  182. /*-------------------------------------------------------------------------*/
  183. int recv_datagram(void *buf, int len, char *sender)    /* recv a datagram    */
  184. {                                                                        /* from any node        */
  185.     int err;
  186.  
  187.     clear_ncb(&ncb);
  188.     ncb.num = 2;
  189.     ncb.buffer = (char far *) buf;
  190.     ncb.length = len;
  191.     err = nb_request(NB_RECEIVE_DATAGRAM, &ncb);
  192.     if(err)
  193.         return(0);
  194.     else
  195.     {
  196.         if(sender)
  197.             namecpy(sender, ncb.callname);
  198.         return(ncb.length);
  199.     }
  200. }
  201.  
  202. /*-------------------------------------------------------------------------*/
  203. int nw_recv_datagram(void *buf, int len, NCB *ncbptr)    /* recv a datagram    */
  204. {                                                                        /* w/no wait option    */
  205.     int err;
  206.  
  207.     ncbptr->num = 2;
  208.     ncbptr->buffer = (char far *) buf;
  209.     ncbptr->length = len;
  210.     return(!nb_request(NB_RECEIVE_DATAGRAM | NO_WAIT, ncbptr));
  211. }
  212.  
  213. /*-------------------------------------------------------------------------*/
  214. int send(int lsn, void *buf, int len)                /* send data to a session    */
  215. {
  216.     clear_ncb(&ncb);
  217.     ncb.lsn = lsn;
  218.     ncb.buffer = (char far *) buf;
  219.     ncb.length = len;
  220.     if(nb_request(NB_SEND, &ncb))
  221.         return(0);
  222.     else
  223.         return(len);
  224. }
  225.  
  226. /*-------------------------------------------------------------------------*/
  227. int receive(int lsn, void *buf, int len)            /* recv data from session    */
  228. {
  229.     int ret;
  230.  
  231.     clear_ncb(&ncb);
  232.     ncb.lsn = lsn;
  233.     ncb.buffer = (char far *) buf;
  234.     ncb.length = len;
  235.     ret = nb_request(NB_RECEIVE, &ncb);
  236.     if(ret == 0 || ret == 6)                    /* success or message incomplete    */
  237.         return(ncb.length);
  238.     else
  239.         return(0);
  240. }
  241.  
  242. /*-------------------------------------------------------------------------*/
  243. int hangup(int lsn)                                /* hang up and clear a session    */
  244. {
  245.     clear_ncb(&ncb);
  246.     ncb.lsn = lsn;
  247.     return(!nb_request(NB_HANGUP, &ncb));
  248. }
  249.